package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.zzyl.dto.DeviceDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DeviceLocationTypeEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.ProductVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    AliIoTConfigProperties aliIoTConfigProperties;
    @Autowired
    Client client;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    DeviceMapper deviceMapper;

    @Override
    public void syncProductList() {
        QueryProductListRequest queryProductListRequest = new QueryProductListRequest();
        //分页条件
        queryProductListRequest.setPageSize(200);
        queryProductListRequest.setCurrentPage(1);
        //公共实例
        queryProductListRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductListResponse queryResponse = null;


        try {
            //查询公共实例下的所有产品
            queryResponse = client.queryProductList(queryProductListRequest);
        } catch (Exception requestFiled) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }

        if (!queryResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }
        List<ProductVo> productVoList = queryResponse.getBody().getData().getList().getProductInfo()
                .stream().map(item -> BeanUtil.toBean(item, ProductVo.class))
                .collect(Collectors.toList());
//        log.info("iot平台获取到的产品列表：productVoList={}", productVoList);
        redisTemplate.opsForValue().set("iot:all_product", productVoList);
    }

    @Override
    public List<ProductVo> allProduct() {
        return (List<ProductVo>) redisTemplate.opsForValue().get("iot:all_product");
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //先判断设备名与数据库中是否存在重复
        String deviceName = deviceDto.getDeviceName();
        Device theDevice = deviceMapper.selectByDeviceName(deviceName);
        log.info("查到的设备属性为：{}",theDevice );
        if (!Objects.isNull(theDevice)) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        //获取注册设备请求，同时存入实例Iot平台的实例id
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse registerDeviceResponse = null;
        try {
            registerDeviceResponse = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //对接口返回结果进行判断
        if (registerDeviceResponse == null || !registerDeviceResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //至此设备注册成功，准备获取产品信息存入数据库
        //先拷贝属性到实体类中
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(registerDeviceResponse.getBody().getData().getIotId());//存入注册的设备的iotId
        //发起查询产品信息请求
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse = null;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }//至此产品信息请求发起成功，并获取了结果
        if (queryProductResponse.getBody().success) {//判断请求结果是否成功。成功则将产品信息存入实体类
            device.setDeviceName(queryProductResponse.getBody().getData().getProductName());
        }
        //存入数据库中判断位置类型是否为0,为0则将物理位置设置为-1
        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())) {
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());
        }
        //正式存入数据库
        try {
            deviceMapper.insert(device);
        } catch (Exception insertFiled) {
            //删除之前存入IOT平台的设备
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setProductKey(device.getProductKey());
            deleteDeviceRequest.setIotId(device.getIotId());
            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception deletesFromIotFiled) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
            //由于存入设备失败，删除之前在IOT平台注册的设备后，再给前端抛出设备存入的异常
            throw new BaseException(BasicEnum.LOCATION_BINDING_PRODUCT);//提示设备已经被绑定
        }
    }
}

